package com.jinke.tank;

import com.jinke.game.Bullet;
import com.jinke.game.Explosion;
import com.jinke.game.GameFrame;
import com.jinke.util.*;

import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static com.jinke.util.Constant.MIN_FONT;

public abstract class Tank {
    //四个方向
    public static final int DIR_UP = 0;
    public static final int DIR_DOWN = 1;
    public static final int DIR_LEFT = 2;
    public static final int DIR_RIGHT = 3;

    // 坦克半径
    public static final int RADIUS = 20;
    // 默认的速度 每帧 移动 2 个像素
    public static final int DEFAULT_SPEED = 2;
    //坦克的状态
    public static final int STATE_NORMAL = 0;
    public static final int STATE_MOVE = 1;
    public static final int STATE_DEAD = 2;
    public boolean[] keyStates = new boolean[4]; // 上、下、左、右四个方向键的状态
    //坦克的初始生命
    public static final int DEFAULT_HP = 1000;

    protected int x,y;

    //边界尺寸
    protected final int boundWidth;
    protected final int boundHeight;

    protected String name;
    protected int hp = DEFAULT_HP;
    protected int atk;
    protected int speed = DEFAULT_SPEED;
    protected int dir;
    protected int state = STATE_NORMAL;

    //炮弹列表
    private final List<Bullet> bullets = new ArrayList<>();
    private final List<Explosion> explosions = new ArrayList<>();

    private BloodBar bar = new BloodBar();

    public Tank(int x, int y, int dir,int boundWidth, int boundHeight) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.boundWidth = boundWidth;
        this.boundHeight = boundHeight;
        name = Myutils.getRandomName();
    }

    public Tank(int x, int y, int dir) {
        this(x, y, dir, GameFrame.gamePanel.getWidth(), GameFrame.gamePanel.getHeight());
    }
    public void drawTank (Graphics g) {
        logic();

        drawImgTank(g);

        drawBullets(g);

        drawName(g);

        bar.drawBloodBar(g);

    }

    public void drawName(Graphics g){
        g.setColor(Color.cyan);
        g.setFont(MIN_FONT);
        g.drawString(name, x-RADIUS, y-30);
    }
    /**
     * 逻辑方法
     */
    public abstract void logic();

    /**
     * 移动的方法
     */
    public void move() {
        switch (dir){
            case DIR_UP:
                y -= speed;
                if (y < RADIUS){
                    y = RADIUS;
                }
                break;
            case DIR_DOWN:
                y += speed;
                if (y > boundHeight-RADIUS){
                    y = boundHeight-RADIUS;
                }
                break;
            case DIR_LEFT:
                x -= speed;
                if (x < RADIUS){
                    x = RADIUS;
                }
                break;
            case DIR_RIGHT:
                x += speed;
                if (x > boundWidth-RADIUS){
                    x = boundWidth-RADIUS;
                }
                break;
        }
    }

    public boolean isPlayerTank() {
        return true; // 默认为我方坦克
    }

    /**
     * 发射炮弹的方法
     */
    public void fire(Tank tank) {
        int bulletX = x;
        int bulletY = y;
        atk = 100;//添加攻击力
        Color bulletColor = isPlayerTank() ? Color.YELLOW : Color.GRAY;
        switch (dir){
            case DIR_UP:
                bulletY -= RADIUS;
                break;
            case DIR_DOWN:
                bulletY += RADIUS;
                break;
            case DIR_LEFT:
                bulletX -= RADIUS;
                break;
            case DIR_RIGHT:
                bulletX += RADIUS;
                break;
        }

        // 获取一个炮弹对象
        Bullet bullet = BulletPool.instance.getBulletObj(bulletX, bulletY, dir, atk, bulletColor);
        bullets.add(bullet);
    }

    /**
     * 绘制炮弹的方法
     * @param g
     */
    private void drawBullets(Graphics g) {

//        for (Bullet bullet : bullets){
//            bullet.drawBullet(g);
//        }
        // 使用迭代器遍历列表,避免了用新列表记录要删除的元素
        Iterator<Bullet> iterator = bullets.iterator();
        while (iterator.hasNext()) {
            Bullet bullet = iterator.next();
            bullet.drawBullet(g);

            // 检查子弹是否飞出边界，如果是则移除并回收
            if (isBulletOutOfBound(bullet)) {
                iterator.remove(); // 使用迭代器安全地移除元素
                BulletPool.instance.freeBulletObj(bullet);
//                System.out.println("子弹飞出边界回收");
            }
        }
    }



    /**
     * 检查子弹是否飞出边界
     * @param bullet 要检查的子弹
     * @return 是否飞出边界
     */
    private boolean isBulletOutOfBound(Bullet bullet) {
        return bullet.getX() < -Bullet.RADIUS ||
                bullet.getX() > boundWidth + Bullet.RADIUS ||
                bullet.getY() < -Bullet.RADIUS ||
                bullet.getY() > boundHeight + Bullet.RADIUS;
    }

    public void collisionCheck(List<Bullet> bullets) {
        Iterator<Bullet> iterator = bullets.iterator();
        while (iterator.hasNext()) {
            Bullet bullet = iterator.next();
            if (Myutils.isCollision(x, y, RADIUS, bullet.getX(), bullet.getY())) {
                // 移除并回收子弹
                iterator.remove();
                BulletPool.instance.freeBulletObj(bullet);
                //对坦克减血
                hurt( bullet);
                //爆炸动画
                ExplosionPool.instance.getExplosion(x, y);
            }
        }
    }

    private void hurt(Bullet bullet){
        int atk =bullet.getAtk();
        hp -= atk;
        if (hp <= 0){
            hp = 0;
            state = STATE_DEAD;
        }
    }

    protected void die(Tank tank){
        if (tank instanceof EnemyTank){
            TankPool.instance.freeEnemyObj(tank);
        }else {
            GameFrame.gameState = Constant.STATE_OVER;
        }
    }


    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public List<Bullet> getBullets() {
        return bullets;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void drawImgTank(Graphics g);


    class BloodBar{
        public static final int BAR_WIDTH = 50;
        public static final int BAR_HEIGHT = 5;
        public void drawBloodBar(Graphics g){
            g.setColor(Color.yellow);
            g.fillRect(x-RADIUS, y-RADIUS-BAR_HEIGHT*2+4, BAR_WIDTH, BAR_HEIGHT);
            g.setColor(Color.red);
            g.fillRect(x-RADIUS, y-RADIUS-BAR_HEIGHT*2+4, hp*BAR_WIDTH/DEFAULT_HP, BAR_HEIGHT);
            g.setColor(Color.white);
            g.drawRect(x-RADIUS, y-RADIUS-BAR_HEIGHT*2+4, BAR_WIDTH, BAR_HEIGHT);
        }
    }
}
